import { CascaderSelect } from '@alifd/next';
import { CascaderSelectProps } from '@alifd/next/types/cascader-select';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { getCities, getExistOffStations, getExistOnStations, getStations } from './api';


interface IBusStationSelect extends CascaderSelectProps {
  forRoute?: boolean;
  fromCity?: string;
  toCity?: string;
  isOffStation?: boolean;
}

function BusStationSelect({ forRoute, ...props }: IBusStationSelect) {
  if (forRoute) {
    return <BusExistStationSelect {...props} />;
  }
  return <BusAllStationSelect {...props} />;
}

function BusAllStationSelect({ ...props }: IBusStationSelect) {
  const [data, setData] = useState([]);
  const flatten = useRef({}).current;

  useEffect(() => {
    (async function fetchData() {
      const items = await getCities();
      setData(items.map(mapper));
    })();
  }, []);

  const mapper = useCallback((v) => {
    const isStation = !!v.itemId;
    const label = v.name;
    const value = isStation ? v.itemId : v.id;
    const item = {
      label,
      value,
      ...v,
    };
    flatten[value] = item;
    item.isLeaf = !isStation;
    return item;
  }, []);


  const onLoadData = async (v) => {
    const item = flatten[v.value];
    if (item.children) return;
    const children = await getStations(v.value);
    item.children = children.map(mapper);
    setData((prev) => [...prev]);
  };

  return (
    <CascaderSelect
      hasClear
      dataSource={data}
      loadData={onLoadData}
      style={{ width: '100%' }}
      {...props}
    />
  );
}

function BusExistStationSelect({ isOffStation, fromCity, toCity, ...props }: IBusStationSelect) {
  const [data, setData] = useState([]);

  useEffect(() => {
    (async function fetchData() {
      const items = isOffStation ? await getExistOffStations({ fromCity, toCity }) : await getExistOnStations({ fromCity, toCity });
      setData(items.map(mapper));
    })();
  }, [fromCity, toCity, isOffStation]);

  const mapper = useCallback((v) => {
    return {
      label: v.area,
      value: v.area,
      children: v.children.map(c => ({
        label: c.name,
        value: c.stationId,
        isLeaf: true,
        ...c,
      })),
    };
  }, []);

  return (
    <CascaderSelect
      hasClear
      dataSource={data}
      // style={{ width: '100%' }}
      {...props}
    />
  );
}

export default BusStationSelect;
